package com.dng.book.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.time.LocalDateTime;
import com.dng.book.dto.LoginRequest;
import com.dng.book.entity.User;
import com.dng.book.mapper.UserMapper;
import com.dng.book.service.TokenService;
import com.dng.book.service.UserService;
import com.dng.book.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 用户服务实现类
 *
 * @author dng
 * @since 2024-01-01
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private TokenService tokenService;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public String login(LoginRequest loginRequest) {
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        String captchaCode = loginRequest.getCaptchaCode();

        // Redis调试日志
        java.util.Set<String> keys = redisUtil.keys("captcha:*");
        log.info("当前Redis captcha相关key: {}", keys);

        // 测试Redis连接
        boolean testResult = redisUtil.set("testkey", "testvalue", 60, java.util.concurrent.TimeUnit.SECONDS);
        String testVal = redisUtil.get("testkey");
        log.info("Redis测试: setResult={}, testkey value={}", testResult, testVal);
        
        // 校验验证码
        String redisKey = "captcha:" + username;
        String realCode = redisUtil.get(redisKey);
        log.info("验证码校验: username='{}', redisKey='{}', 用户输入={}, redis中={}", username, redisKey, captchaCode, realCode);
        
        if (realCode == null || !realCode.equalsIgnoreCase(captchaCode)) {
            throw new RuntimeException("验证码错误");
        }
        
        // 验证码只用一次
        redisUtil.delete(redisKey);

        log.info("用户登录请求 - 用户名: {}", username);
        log.info("用户登录请求 - 密码长度: {}", password != null ? password.length() : 0);

        // 查询用户
        User user = getByUsername(username);
        if (user == null) {
            log.error("用户不存在 - 用户名: {}", username);
            throw new RuntimeException("用户不存在");
        }

        log.info("查询到用户 - 用户ID: {}, 用户名: {}", user.getId(), user.getUsername());
        log.info("数据库中的密码哈希: {}", user.getPassword());
        log.info("用户输入的密码: {}", password);

        // 验证密码
        String inputPasswordHash = DigestUtil.md5Hex(password);
        log.info("登录验证 - 输入密码: {}, 输入密码哈希: {}", password, inputPasswordHash);
        log.info("登录验证 - 数据库密码哈希: {}", user.getPassword());
        boolean passwordMatch = inputPasswordHash.equals(user.getPassword());
        log.info("密码验证结果: {}", passwordMatch);
        
        if (!passwordMatch) {
            log.error("密码验证失败 - 用户名: {}, 输入密码: {}, 数据库密码哈希: {}", 
                     username, password, user.getPassword());
            throw new RuntimeException("密码错误");
        }

        log.info("用户登录成功 - 用户名: {}", username);
        // 生成Token并存储到Redis
        String token = tokenService.generateAndStoreToken(username);
        return token;
    }

    @Override
    public User getByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return null;
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        return getOne(wrapper);
    }
    
    @Override
    public User getByPhone(String phone) {
        if (StrUtil.isBlank(phone)) {
            return null;
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        return getOne(wrapper);
    }
    
    @Override
    public boolean existsByPhone(String phone) {
        if (StrUtil.isBlank(phone)) {
            log.warn("手机号为空");
            return false;
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        wrapper.eq(User::getDelFlag, "0"); // 只查询未删除的用户
        
        long count = count(wrapper);
        log.info("手机号查询: phone={}, count={}", phone, count);
        
        return count > 0;
    }
    
    @Override
    public boolean resetPasswordByPhone(String phone, String newPassword) {
        try {
            if (StrUtil.isBlank(phone) || StrUtil.isBlank(newPassword)) {
                return false;
            }
            
            // 查询用户
            User user = getByPhone(phone);
            if (user == null) {
                log.error("用户不存在 - 手机号: {}", phone);
                return false;
            }
            
            // 加密新密码
            String encryptedPassword = DigestUtil.md5Hex(newPassword);
            log.info("重置密码 - 新密码: {}, 加密后: {}", newPassword, encryptedPassword);
            
            // 使用LambdaUpdateWrapper更新，避免乐观锁问题
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(User::getPhone, phone)
                    .eq(User::getDelFlag, "0")
                    .set(User::getPassword, encryptedPassword)
                    .set(User::getUpdatedBy, "system")
                    .set(User::getUpdatedTime, LocalDateTime.now());
            
            boolean success = update(updateWrapper);
            
            if (success) {
                log.info("密码重置成功 - 手机号: {}, 用户ID: {}", phone, user.getId());
                
                // 验证更新是否真的成功
                User updatedUser = getByPhone(phone);
                if (updatedUser != null) {
                    log.info("验证更新 - 新密码哈希: {}", updatedUser.getPassword());
                    log.info("验证更新 - 密码是否匹配: {}", updatedUser.getPassword().equals(encryptedPassword));
                } else {
                    log.error("验证更新失败 - 无法查询到更新后的用户");
                }
            } else {
                log.error("密码重置失败 - 手机号: {}", phone);
            }
            
            return success;
        } catch (Exception e) {
            log.error("密码重置异常 - 手机号: {}", phone, e);
            return false;
        }
    }
    
    @Override
    public boolean uploadAvatar(String username, String avatarUrl) {
        try {
            if (StrUtil.isBlank(username) || StrUtil.isBlank(avatarUrl)) {
                return false;
            }
            
            // 检查数据长度
            int avatarLength = avatarUrl.length();
            log.info("头像数据长度: {} 字符", avatarLength);
            
            // TEXT类型最大支持65,535字符，如果超过这个限制，需要截断或压缩
            if (avatarLength > 65535) {
                log.error("头像数据过长: {} 字符，超过TEXT类型限制", avatarLength);
                return false;
            }
            
            // 查询用户
            User user = getByUsername(username);
            if (user == null) {
                log.error("用户不存在 - 用户名: {}", username);
                return false;
            }
            
            // 使用LambdaUpdateWrapper更新，避免乐观锁问题
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(User::getUsername, username)
                    .eq(User::getDelFlag, "0")
                    .set(User::getAvatar, avatarUrl)
                    .set(User::getUpdatedBy, "system")
                    .set(User::getUpdatedTime, LocalDateTime.now());
            
            boolean success = update(updateWrapper);
            
            if (success) {
                log.info("头像上传成功 - 用户名: {}, 头像URL长度: {}", username, avatarLength);
            } else {
                log.error("头像上传失败 - 用户名: {}", username);
            }
            
            return success;
        } catch (Exception e) {
            log.error("头像上传异常 - 用户名: {}, 错误: {}", username, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public String getAvatar(String username) {
        try {
            if (StrUtil.isBlank(username)) {
                return null;
            }
            
            User user = getByUsername(username);
            if (user == null) {
                log.error("用户不存在 - 用户名: {}", username);
                return null;
            }
            
            return user.getAvatar();
        } catch (Exception e) {
            log.error("获取头像异常 - 用户名: {}", username, e);
            return null;
        }
    }

    /**
     * 测试密码加密和验证
     * 用于调试密码问题
     */
    public void testPasswordEncryption() {
        String testPassword = "123456";
        log.info("=== 密码加密测试 ===");
        log.info("测试密码: {}", testPassword);
        
        // 生成密码哈希
        String hashedPassword = DigestUtil.md5Hex(testPassword);
        log.info("生成的密码哈希: {}", hashedPassword);
        
        // 验证密码
        boolean isValid = DigestUtil.md5Hex(testPassword).equals(hashedPassword);
        log.info("密码验证结果: {}", isValid);
        
        // 测试错误的密码
        boolean isInvalid = DigestUtil.md5Hex("wrongpassword").equals(hashedPassword);
        log.info("错误密码验证结果: {}", isInvalid);
        
        log.info("=== 测试完成 ===");
    }
} 